#include "xrj_protocol.h"
#include "I2c_lkt4106.h"
#include  "queue.h"
#include "xrj_mutex_lock.h"

#include "usart1.h"
#include "usart2.h"
#include "usart3.h"
#include "usart5.h"

const char Version2Flash[256] __attribute__((at(0x8008000+2048))) = {  	
	's','o','f','t','w','a','r','e',':', 
	((SOFTWARE_VESION&0xf000)>>12)+0x30,((SOFTWARE_VESION&0x0f00)>>8)+0x30,'.',((SOFTWARE_VESION&0x00f0)>>4)+0x30,((SOFTWARE_VESION&0x000f)>>0)+0x30,',',
	'h','a','r','d','w','a','r','e',':', 
	((HAREWARE_VESION&0xf000)>>12)+0x30,((HAREWARE_VESION&0x0f00)>>8)+0x30,'.',((HAREWARE_VESION&0x00f0)>>4)+0x30,((HAREWARE_VESION&0x000f)>>0)+0x30,',',
	'b','u','i','l','d',':',
	YEAR_0,YEAR_1,YEAR_2,YEAR_3,
	MONTH_0,MONTH_1,
	DAY_0,DAY_1,
	TIME_0,TIME_1,TIME_2,TIME_3,
	0,	
};

#define DEBUG_PROTOBUF		1
INT32 OTA_CHECK_END(UINT8 *OtaMessage);
st_OTA	OTA_FLASH;	

st_Device_Value 	Device_Value; 

/********************需修改部分*******sssss****************************************************/
#define Device_NUM			25
Device_Descriptor 	Device[Device_NUM] = 
{
	{IOT__UNIT_INDEX__ROM_VERSION, IOT__VALUE_TYPES__STRING, IOT__ACTION_CODES__QUERY},
	{IOT__UNIT_INDEX__LED_1, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},	//指示灯LED 1
	{IOT__UNIT_INDEX__LED_2, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},	//指示灯LED 2
	
	{IOT__UNIT_INDEX__KEY_1, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY},								//按键KEY 1
	{IOT__UNIT_INDEX__KEY_2, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY},								//按键KEY 2
	
	
	
	{IOT__UNIT_INDEX__WEIGHING_1, IOT__VALUE_TYPES__INT64, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},							//重量传感器1
	{IOT__UNIT_INDEX__WEIGHING_2, IOT__VALUE_TYPES__INT64, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},							//重量传感器2
	
	{IOT__UNIT_INDEX__TRASH_CAPACITY_1, IOT__VALUE_TYPES__INT64, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY},						//垃圾桶容量传感器1
	{IOT__UNIT_INDEX__TRASH_CAPACITY_2, IOT__VALUE_TYPES__INT64, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY},						//垃圾桶容量传感器2
	
	{IOT__UNIT_INDEX__PLATE_1, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},								//门1	
	{IOT__UNIT_INDEX__PLATE_2, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},								//门2
	
	{IOT__UNIT_INDEX__IC_CARD, 	IOT__VALUE_TYPES__UINT32, IOT__ACTION_CODES__REPORT},														//IC刷卡器	
	{IOT__UNIT_INDEX__IC_BLOCK_2, 	IOT__VALUE_TYPES__BYTES, IOT__ACTION_CODES__REPORT},														//IC刷卡器	第2块
	
	{IOT__UNIT_INDEX__LIGHT_INSIDE_1, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},	//照明灯
	{IOT__UNIT_INDEX__LIGHT_INSIDE_2, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},	//照明灯
	{IOT__UNIT_INDEX__LIGHT_OUTSIDE_1, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},	//照明灯
	{IOT__UNIT_INDEX__LIGHT_OUTSIDE_2, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},	//照明灯	
	{IOT__UNIT_INDEX__TEMPERATURE, 	IOT__VALUE_TYPES__INT64, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY},
	
	{IOT__UNIT_INDEX__LOCK_1, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},
	{IOT__UNIT_INDEX__LOCK_2, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},
	
	{IOT__UNIT_INDEX__SENSOR_1, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},
	{IOT__UNIT_INDEX__SENSOR_2, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},
	
	{IOT__UNIT_INDEX__FAN, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__SETTING},
	
	{IOT__UNIT_INDEX__RUNNING_STATUS, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},
	{IOT__UNIT_INDEX__RUNNING_ERROR, 	IOT__VALUE_TYPES__STATUS, IOT__ACTION_CODES__REPORT|IOT__ACTION_CODES__QUERY|IOT__ACTION_CODES__SETTING},
};



/********************需修改部分********eeeeee***************************************************/


#define	Proto_TIMEOUT		100


St_Proto_TxRx  	ProtoTxRx;
St_Session_Flag	Session_Flag1;


extern OS_EVENT * USART2_Recv_Sem;

INT32 Wrapper_Decode_Product(UINT8 * buf, INT32 len);
INT32 Session_Realse(UINT32 session);




void MCU_Reset(void)
{

	OSTimeDlyHMSM (0,0,0,100);
	__set_FAULTMASK(1);     
	NVIC_SystemReset();
		
}




//=================转换函数
void int64ToUint8(UINT8*buf, INT64 data){
	UINT64 uData = (UINT64)data;
	for (INT32 i=0; i<8; i++){
		buf[7-i] = uData&0xff;
		uData = uData>>8;
	}
}

void int32ToUint8(UINT8*buf, INT32 data){
	UINT64 uData = (UINT32)data;
	for (INT32 i=0; i<4; i++){
		buf[3-i] = uData&0xff;
		uData = uData>>8;
	}
}

void int16ToUint8(UINT8*buf, UINT16 data){
	UINT64 uData = (UINT16)data;
	for (INT32 i=0; i<2; i++){
		buf[1-i] = uData&0xff;
		uData = uData>>8;
	}
}


INT64 uint8ToInt64(UINT8* buf){
	UINT64 uData = 0;
	for (INT32 i=0; i<8; i++){
		uData = uData<<8;
		uData += buf[i];
	}
	return (INT64)uData;
}

INT32 uint8ToInt32(UINT8*buf){
	UINT32 uData = 0;
	for (INT32 i=0; i<4; i++){
		uData = uData<<8;
		uData += buf[i];
	}
	return (INT32)uData;
}

UINT32 uint8ToUint32(UINT8* buf){
	UINT32 uData = 0;
	for (INT32 i=0; i<4; i++){
		uData = uData<<8;
		uData += buf[i];
	}
	return (UINT32)uData;
}

UINT16 uint8ToUint16(UINT8*buf){
	UINT16 uData = 0;
	for (INT32 i=0; i<2; i++){
		uData = uData<<8;
		uData += buf[i];
	}
	return uData;
}


UINT8 checkSum(UINT8 *buf, INT32 len){
	UINT8 ret = 0;
	for (INT32 i=0; i<len; i++){
		ret ^= buf[i];
	}
	return ret;
}

INT32 byteTo4BitArray(UINT8 *src, UINT8 *dist, INT32 len){
	dist[0] = 0xff;
	dist[len*2+1] = 0xfe;
	for (INT32 i=0; i<len; i++){
		UINT8 bit4Hight = (src[i]>>4)&0x0f;
		UINT8 bit4Low = src[i]&0x0f;
		dist[1 + i*2] = bit4Hight;
		dist[1 + i*2+1] = bit4Low; 
	}
	return 0;
}

INT32 decodeUartRx(UINT8 *src, UINT8 *dist, INT32 len){
	INT32 ret = -1;
	INT32 err = 0;
	if ((src[0]==0xff)
		&&(src[len-1]==0xfe)){
		for (INT32 i = 0; i<len;i++){
			if ((0<i)&&(i<(len-1))){
				if ((src[i]&0xf0) != 0){
					err = -1;
				}
			}
		}
		//===编码正确
		if (err==0){
			for (INT32 j = 0; j<(len-2)/2; j++){
					dist[j] = ((src[1+j*2]<<4)&0xf0)|(src[1+j*2+1]&0x0f);
			}
			//==0xff不校验
			if (dist[(len-2)/2-1] == checkSum(&dist[0], (len-2)/2-1)){
					ret = 0;
			}		
		}	
	}
	
	return ret;
}
//==============================================




void ProtoTxRx_Create_Sem(void)
{	
#if OS_CRITICAL_METHOD == 3u
    OS_CPU_SR cpu_sr=0u;
#endif
    OS_ENTER_CRITICAL();  //进入临界区(关闭中断)
    XRJ_mutex_init(&ProtoTxRx.Lock);   
	XRJ_mutex_init(&Device_Value.Lock);	
	
	Device_Value.LED_1_Report = IOT__STATUS_CODES__OFF;
	Device_Value.LED_2_Report = IOT__STATUS_CODES__OFF;
	
	Device_Value.LIGHT_INSIDE_1_Report = IOT__STATUS_CODES__OFF;
	Device_Value.LIGHT_INSIDE_2_Report = IOT__STATUS_CODES__OFF;
	
	Device_Value.LIGHT_OUTSIDE_1_Report = IOT__STATUS_CODES__OFF;
	Device_Value.LIGHT_OUTSIDE_2_Report = IOT__STATUS_CODES__OFF;
	
	
	Device_Value.PLATE_1_Report = IOT__STATUS_CODES__DOING;
	Device_Value.PLATE_2_Report = IOT__STATUS_CODES__DOING;
	
	Device_Value.PLATE_1_Setting = IOT__STATUS_CODES__NONE;
	Device_Value.PLATE_2_Setting = IOT__STATUS_CODES__NONE;
	
	Device_Value.PLATE_1_Setting_Time = 5;	//==默认5秒
	Device_Value.PLATE_2_Setting_Time = 5;	//==默认5秒
	
	
	
	Device_Value.KEY_1 = IOT__STATUS_CODES__UP;
	Device_Value.KEY_2 = IOT__STATUS_CODES__UP;
		
	Device_Value.TRASH_CAPACITY_1_Report = 2000;
	Device_Value.TRASH_CAPACITY_2_Report = 2000;
	
	Device_Value.WEIGHING_1_Report = 0x8000000000000000;
	Device_Value.WEIGHING_2_Report = 100000;
	
	Device_Value.LOCK_1_Report = IOT__STATUS_CODES__OFF;
	Device_Value.LOCK_2_Report = IOT__STATUS_CODES__OFF;
	
	Device_Value.SENSOR_1_Report = IOT__STATUS_CODES__OFF;
	Device_Value.SENSOR_2_Report = IOT__STATUS_CODES__OFF;
	
//	sprintf(Device_Value.VERSION,"%d.%d,%d.%d,%d%02d%02d%04d",(SOFTWARE_VESION/256),(SOFTWARE_VESION%256),
//															 (HAREWARE_VESION/256),(HAREWARE_VESION%256), 
//																YEAR,MONTH,DAY,TIME);
	sprintf(Device_Value.VERSION,"%02x.%02x,%02x.%02x,%s",(SOFTWARE_VESION/256),(SOFTWARE_VESION%256),
															 (HAREWARE_VESION/256),(HAREWARE_VESION%256), 
																&Version2Flash[36]);															 
	
    OS_EXIT_CRITICAL();  //退出临界区(开中断)
}

INT32 Get_ProtoTxRx_Index(void)
{
INT32 i;
INT32 j = -1;	
	XRJ_mutex_lock(&ProtoTxRx.Lock);
	for (i = 0; i < TX_Num; i++)
	{
		if (ProtoTxRx.Packet[i].Status == Proto_Tx_Free)
		{
			j = i;
			break;
		}	
	}
	XRJ_mutex_unlock(&ProtoTxRx.Lock);
	return j;
}	

INT32 TxPacket_Init(UINT8 *buf, UINT32 len, UINT32 session, UINT32 TimeoutNum, ProtoFlag Flag)
{
INT32 offset;	
	offset = Get_ProtoTxRx_Index();
	if (offset < 0)
		return -1;
	XRJ_mutex_lock(&ProtoTxRx.Lock);
	ProtoTxRx.Packet[offset].session = session;
	ProtoTxRx.Packet[offset].len = len;
	ProtoTxRx.Packet[offset].TXbuf = buf;
	ProtoTxRx.Packet[offset].TimeoutNum = TimeoutNum;
	ProtoTxRx.Packet[offset].TimeoutCnt = 0;
	ProtoTxRx.Packet[offset].Timeout = Proto_TIMEOUT;
	ProtoTxRx.Packet[offset].Status = Proto_Tx_Busy;
	ProtoTxRx.Packet[offset].Flag = Flag;
	XRJ_mutex_unlock(&ProtoTxRx.Lock);
	return  0;
}	


void TxPacket_Realse_Loop(void)
{
	INT32 i;
	XRJ_mutex_lock(&ProtoTxRx.Lock);
	for (i = 0; i < TX_Num; i++)
	{
		if (ProtoTxRx.Packet[i].Status == Proto_Tx_ToFree)
		{
			free(ProtoTxRx.Packet[i].TXbuf);
			ProtoTxRx.Packet[i].Status = Proto_Tx_Free;
		}	
	}
	XRJ_mutex_unlock(&ProtoTxRx.Lock);	
}


void TxPacket_Send_Loop(void)
{
	INT32 i;

	for (i = 0; i < TX_Num; i++)
	{
		ProtoTxRx.len = 0;
		
		XRJ_mutex_lock(&ProtoTxRx.Lock);
		if (ProtoTxRx.Packet[i].Status == Proto_Tx_Busy)
		{
			if (ProtoTxRx.Packet[i].Flag == Flag_Response)
			{
				memcpy(ProtoTxRx.BUF,ProtoTxRx.Packet[i].TXbuf,ProtoTxRx.Packet[i].len);
				ProtoTxRx.len = ProtoTxRx.Packet[i].len;
				ProtoTxRx.Packet[i].Status = Proto_Tx_ToFree;
			}
			else
			{
				ProtoTxRx.Packet[i].Timeout++;	
				if ( (ProtoTxRx.Packet[i].Timeout >= Proto_TIMEOUT) && 
					((ProtoTxRx.Packet[i].TimeoutNum == 0) || (ProtoTxRx.Packet[i].TimeoutNum >= ProtoTxRx.Packet[i].TimeoutCnt)))
				{
					//------判断是否超时结束
					if (ProtoTxRx.Packet[i].TimeoutNum != 0)
					{
						ProtoTxRx.Packet[i].TimeoutCnt++;
						if (ProtoTxRx.Packet[i].TimeoutCnt > ProtoTxRx.Packet[i].TimeoutNum)
						{
							if (ProtoTxRx.Packet[i].Flag == FeedBack_Enable)
							{
								ProtoTxRx.Packet[i].Status = Proto_Tx_FALSE;	
							}			
							else
							{
								ProtoTxRx.Packet[i].Status = Proto_Tx_ToFree;
							}	
						}				
					}	

					if (ProtoTxRx.Packet[i].Status == Proto_Tx_Busy)
					{						
						memcpy(ProtoTxRx.BUF,ProtoTxRx.Packet[i].TXbuf,ProtoTxRx.Packet[i].len);
						ProtoTxRx.len = ProtoTxRx.Packet[i].len;
						ProtoTxRx.Packet[i].Timeout = 0;
						printf("TxPacket_Send_Loop send\n");
					}	
				}
			}
		}	
		XRJ_mutex_unlock(&ProtoTxRx.Lock);		
		if (ProtoTxRx.len > 0)
		{	
			USART2_DMA_WRITE(ProtoTxRx.BUF, ProtoTxRx.len);
			break;
		}
	}	
}	

void RxPacket_Receive_Loop(void)
{
	INT16 ret = 0;
	UINT8 buf[512];
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
		OS_CPU_SR  cpu_sr = 0u;
#endif			
	ret = OSSemAccept(USART2_Recv_Sem);
	if(ret > 0)
	{
		//	memset(ProtoTxRx.BUF,0,20);
			OS_ENTER_CRITICAL();
			ProtoTxRx.len = Dequeue(&Queue_Frame_Usart2,(uint8_t *)ProtoTxRx.BUF,DMA_RX2_LEN);
			OS_EXIT_CRITICAL();		
			if (ProtoTxRx.len > 0)
			{
				INT32 result = 0;
				result = decodeUartRx(ProtoTxRx.BUF, buf, ProtoTxRx.len);
				if (result >= 0)
				{
					Wrapper_Decode_Product(buf, ProtoTxRx.len/2);
				}
				else
				{	
					printf("protobuf: false\n");					

				}
			}	
	}		
}

/**
  * @brief  获取一个新的流水号
  * @param  session: 流水号
  * @retval  
  */
UINT32 Session_GetNew(void)
{
	INT32 i;
	UINT32 session;
	INT32 ret = 0;	
	XRJ_mutex_lock(&ProtoTxRx.Lock);
	while(1)
	{	
		ProtoTxRx.session++;
		for (i = 0; i < TX_Num; i++)
		{
			if (ProtoTxRx.session == ProtoTxRx.Packet[i].session)
			{
				ret = -1;
				break;
			}
		}
		if (ret == 0)
		{
			break;
		}	
	}
	session = ProtoTxRx.session;
	XRJ_mutex_unlock(&ProtoTxRx.Lock);
	return session;
}	


/**
  * @brief  查询某个流水号是否已应答
  * @param  session: 流水号
  * @retval  -1: 未应答
			  0: 已应答
  */
INT32 Session_Poll(UINT32  session)
{

	INT32 i;
	INT32 ret = 0;
	XRJ_mutex_lock(&ProtoTxRx.Lock);
	for (i = 0; i < TX_Num; i++)
	{
		if ((ProtoTxRx.Packet[i].Status == Proto_Tx_Busy)&&(ProtoTxRx.Packet[i].session  == session))
		{
			ret = -1;
			break;
		} 
		if ((ProtoTxRx.Packet[i].Status == Proto_Tx_FALSE)&&(ProtoTxRx.Packet[i].session  == session))
		{	
			ret = -2;
			break;
		}	
	}	
	XRJ_mutex_unlock(&ProtoTxRx.Lock);
	return ret;
}
/**
  * @brief  释放 要求反馈的超时流水号
  * @param  session: 流水号
  * @retval  
  */
INT32 Session_FALSE_Release(UINT32  session)
{

	INT32 i;
	INT32 ret = 0;
	printf("Session_FALSE_Release \n");
	XRJ_mutex_lock(&ProtoTxRx.Lock);
	for (i = 0; i < TX_Num; i++)
	{
		if ((ProtoTxRx.Packet[i].Status == Proto_Tx_FALSE)&&(ProtoTxRx.Packet[i].session  == session))
		{	
			ProtoTxRx.Packet[i].Status = Proto_Tx_ToFree;
			break;
		}	
	}	
	XRJ_mutex_unlock(&ProtoTxRx.Lock);
	return ret;
}

/**
  * @brief  收到应答释放流水号
  * @param  session: 流水号
  * @retval  
  */
INT32 Session_Release(UINT32 session)
{
	INT32 i;
	XRJ_mutex_lock(&ProtoTxRx.Lock);
	for (i = 0; i < TX_Num; i++)
	{
		if ((ProtoTxRx.Packet[i].Status == Proto_Tx_Busy)&&(ProtoTxRx.Packet[i].session  == session)) 
		{
			ProtoTxRx.Packet[i].Status = Proto_Tx_ToFree;
			break;
		}	
	}
	XRJ_mutex_unlock(&ProtoTxRx.Lock);
	return 0;
}	

/********************需修改部分*******sssss****************************************************/
#if DEBUG_PROTOBUF
typedef struct _st_DEVICE_MAP{
	UINT32	index;
	INT8	tab[10];
}st_DEVICE_MAP;

const st_DEVICE_MAP DEVICE_MAP[5] = 
{
	{IOT__UNIT_INDEX__LED_1,"LED_1"},
	{IOT__UNIT_INDEX__LED_2,"LED_2"},
	{IOT__UNIT_INDEX__LIGHT,"LIGHT"},
	{IOT__UNIT_INDEX__PLATE_1,"PLATE_1"},
	{IOT__UNIT_INDEX__PLATE_2,"PLATE_2"},	
};	
#endif

INT32 TLV_To_Value(UINT8 *buf)
{
	UINT8 type = buf[0];
	UINT16 tlen = uint8ToUint16(&buf[1]);
	XRJ_mutex_lock(&Device_Value.Lock);
	switch(type)
	{
		case IOT__UNIT_INDEX__ROM_VERSION:		 
			memcpy((UINT8*)Device_Value.VERSION, &buf[3], tlen);
			break;
				
		case  IOT__UNIT_INDEX__LED_1:
			Device_Value.LED_1_Setting = (Iot__StatusCodes)buf[3];
			break;
		case  IOT__UNIT_INDEX__LED_2:	
			Device_Value.LED_2_Setting = (Iot__StatusCodes)buf[3];
			break;
		case  IOT__UNIT_INDEX__KEY_1:
			Device_Value.KEY_1 = (Iot__StatusCodes)buf[3];
			break;
		case  IOT__UNIT_INDEX__KEY_2:
			Device_Value.KEY_2 = (Iot__StatusCodes)buf[3];
			break;			
		
		case  IOT__UNIT_INDEX__WEIGHING_1:
			Device_Value.WEIGHING_1_Setting = uint8ToInt64(&buf[3]);
			break;
		case  IOT__UNIT_INDEX__WEIGHING_2:
			Device_Value.WEIGHING_2_Setting = uint8ToInt64(&buf[3]);;
			break;
	
		case  IOT__UNIT_INDEX__TRASH_CAPACITY_1:
			Device_Value.TRASH_CAPACITY_1_Setting = uint8ToInt64(&buf[3]);
			break;
			
		case  IOT__UNIT_INDEX__TRASH_CAPACITY_2:
			Device_Value.TRASH_CAPACITY_2_Setting = uint8ToInt64(&buf[3]);
			break;
					

		case  IOT__UNIT_INDEX__PLATE_1:
			Device_Value.PLATE_1_Setting = (Iot__StatusCodes)buf[3];
			//===带开关时长
			if (tlen==2){
				Device_Value.PLATE_1_Setting_Time = buf[4];
			}else{
				Device_Value.PLATE_1_Setting_Time = 5;
			}
			
			break;		
		
		case  IOT__UNIT_INDEX__PLATE_2:
			Device_Value.PLATE_2_Setting = (Iot__StatusCodes)buf[3];
			//===带开关时长
			if (tlen==2){
				Device_Value.PLATE_2_Setting_Time = buf[4];
			}else{
				Device_Value.PLATE_2_Setting_Time = 5;
			}
			break;		
		
		case  IOT__UNIT_INDEX__IC_CARD:
			Device_Value.IC_CARD = uint8ToUint32(&buf[3]);		
			break;
		case  IOT__UNIT_INDEX__IC_BLOCK_2:
			if (tlen > 16)			{	
				memcpy(Device_Value.IC_BLOCK_2, &buf[3],16);
			}
			else
			{
				memcpy(Device_Value.IC_BLOCK_2, &buf[3], tlen);
			}	
			break;	
			
		case  IOT__UNIT_INDEX__LIGHT_INSIDE_1:
			Device_Value.LIGHT_INSIDE_1_Setting = (Iot__StatusCodes)buf[3];
			break;	
		case  IOT__UNIT_INDEX__LIGHT_INSIDE_2:
			Device_Value.LIGHT_INSIDE_2_Setting = (Iot__StatusCodes)buf[3];
			break;	

		case  IOT__UNIT_INDEX__LIGHT_OUTSIDE_1:
			Device_Value.LIGHT_OUTSIDE_1_Setting = (Iot__StatusCodes)buf[3];
			break;	
		case  IOT__UNIT_INDEX__LIGHT_OUTSIDE_2:
			Device_Value.LIGHT_OUTSIDE_2_Setting = (Iot__StatusCodes)buf[3];
			break;		

		case IOT__UNIT_INDEX__TEMPERATURE:
			Device_Value.TEMPERATURE_Report = uint8ToInt64(&buf[3]);
			break;		
		
		case IOT__UNIT_INDEX__LOCK_1:
			Device_Value.LOCK_1_Setting = (Iot__StatusCodes)buf[3];
			break;
		case IOT__UNIT_INDEX__LOCK_2:
			Device_Value.LOCK_2_Setting = (Iot__StatusCodes)buf[3];		
			break;
		case IOT__UNIT_INDEX__FAN:
			Device_Value.FAN_Setting = (Iot__StatusCodes)buf[3];		
			break;			
	}	
	XRJ_mutex_unlock(&Device_Value.Lock);
	

	return 0;
}

//废弃
INT32 Value_To_TLV_Response(UINT8 *buf, INT32 type)
{
	INT32 i;
	INT32 len = 0;
	INT32 ret = -1;
	for (i = 0; i < Device_NUM; i++)
	{
		if (Device[i].index == type)
		{
			ret = 0;
			break;
		}	
	}
	if (ret == -1)
		return ret;
	
	XRJ_mutex_lock(&Device_Value.Lock);
	buf[0] = type;
	switch(type)
	{
		case IOT__UNIT_INDEX__ROM_VERSION:
			buf[1] = 0;
			buf[2] = sizeof(Device_Value.VERSION)+1;
		  buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			memcpy(&buf[4], (UINT8*)Device_Value.VERSION, sizeof(Device_Value.VERSION));
			len = 4 + sizeof(Device_Value.VERSION);
			break;
		case  IOT__UNIT_INDEX__LED_1:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.LED_1_Report;
			len = 5;
			break;
		case  IOT__UNIT_INDEX__LED_2:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.LED_2_Report;
			len = 5;			
			break;
		case  IOT__UNIT_INDEX__KEY_1:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.KEY_1;
			len = 5;		
			break;
		case  IOT__UNIT_INDEX__KEY_2:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.KEY_2;
			len = 5;
			break;					
		case  IOT__UNIT_INDEX__WEIGHING_1:
			buf[1] = 0;
			buf[2] = 8+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			int64ToUint8(&buf[4],Device_Value.WEIGHING_1_Report);
			len = 4+8;	
			break;
		case  IOT__UNIT_INDEX__WEIGHING_2:
			buf[1] = 0;
			buf[2] = 8+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			int64ToUint8(&buf[4],Device_Value.WEIGHING_2_Report);
			len = 4+8;	
			break;
	
		case  IOT__UNIT_INDEX__TRASH_CAPACITY_1:
			buf[1] = 0;
			buf[2] = 8+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			int64ToUint8(&buf[4],Device_Value.TRASH_CAPACITY_1_Report);
			len = 4+8;
			break;
			
		case  IOT__UNIT_INDEX__TRASH_CAPACITY_2:
			buf[1] = 0;
			buf[2] = 8+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			int64ToUint8(&buf[4],Device_Value.TRASH_CAPACITY_2_Report);
			len = 4+8;
			break;
					


		case  IOT__UNIT_INDEX__PLATE_1:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.PLATE_1_Report;
			len = 5;
			break;		
		
		case  IOT__UNIT_INDEX__PLATE_2:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.PLATE_2_Report;
			len = 5;

			break;		
		
		case  IOT__UNIT_INDEX__IC_CARD:
			buf[1] = 0;
			buf[2] = 4+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			int32ToUint8(&buf[4],Device_Value.IC_CARD);
			len = 4+4;
			break;	

		case  IOT__UNIT_INDEX__IC_BLOCK_2:
			buf[1] = 0;
			buf[2] = sizeof(Device_Value.VERSION)+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			memcpy(&buf[4], (UINT8*)Device_Value.IC_BLOCK_2, 16);
			len = 4 + 16;		
			break;			
		case  IOT__UNIT_INDEX__LIGHT_INSIDE_1:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.LIGHT_INSIDE_1_Report;
			len = 5;

			break;	
		case  IOT__UNIT_INDEX__LIGHT_INSIDE_2:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.LIGHT_INSIDE_2_Report;
			len = 5;
			break;	

		case  IOT__UNIT_INDEX__LIGHT_OUTSIDE_1:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.LIGHT_OUTSIDE_1_Report;
			len = 5;
			break;	
		case  IOT__UNIT_INDEX__LIGHT_OUTSIDE_2:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.LIGHT_OUTSIDE_2_Report;
			len = 5;
			break;	
		
		case IOT__UNIT_INDEX__TEMPERATURE:
			buf[1] = 0;
			buf[2] = 8+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			int64ToUint8(&buf[4],Device_Value.TEMPERATURE_Report);
			len = 4+8;
			break;	
		
		case IOT__UNIT_INDEX__LOCK_1:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.LOCK_1_Report;
			len = 5;
			break;
		case IOT__UNIT_INDEX__LOCK_2:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.LOCK_2_Report;
			len = 5;	
			break;
		case IOT__UNIT_INDEX__SENSOR_1:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.SENSOR_1_Report;
			len = 5;
			break;
		case IOT__UNIT_INDEX__SENSOR_2:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.SENSOR_2_Report;
			len = 5;	
			break;
		case IOT__UNIT_INDEX__FAN:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_SUCCESS;
			buf[4] = Device_Value.FAN_Setting;
			len = 5;		
			break;
		case IOT__UNIT_INDEX__RUNNING_ERROR:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_ERROR;
			buf[4] = IOT__ERROR_CODES__ERROR;
			len = 5;		
			break;
		case IOT__UNIT_INDEX__RUNNING_STATUS:
			buf[1] = 0;
			buf[2] = 1+1;
			buf[3] = IOT__RESULT_CODES__RST_ERROR;
			buf[4] = IOT__ERROR_CODES__ERROR;
			len = 5;		
			break;
		default:
			break;
		
	}	
	XRJ_mutex_unlock(&Device_Value.Lock);
	return len;
}
  

INT32 Value_To_TLV(UINT8 *buf, INT32 type)
{
	INT32 i;
	INT32 len = 0;
	INT32 ret = -1;
	for (i = 0; i < Device_NUM; i++)
	{
		if (Device[i].index == type)
		{
			ret = 0;
			break;
		}	
	}
	if (ret == -1)
		return ret;
	
	XRJ_mutex_lock(&Device_Value.Lock);
	buf[0] = type;
	switch(type)
	{
		case IOT__UNIT_INDEX__ROM_VERSION:
			buf[1] = 0;
			buf[2] = sizeof(Device_Value.VERSION);
			memcpy(&buf[3], (UINT8*)Device_Value.VERSION, sizeof(Device_Value.VERSION));
			len = 3 + sizeof(Device_Value.VERSION);
			break;
		case  IOT__UNIT_INDEX__LED_1:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.LED_1_Report;
			len = 4;
			break;
		case  IOT__UNIT_INDEX__LED_2:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.LED_2_Report;
			len = 4;			
			break;
		case  IOT__UNIT_INDEX__KEY_1:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.KEY_1;
			len = 4;		
			break;
		case  IOT__UNIT_INDEX__KEY_2:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.KEY_2;
			len = 4;
			break;					
		case  IOT__UNIT_INDEX__WEIGHING_1:
			buf[1] = 0;
			buf[2] = 8;
			int64ToUint8(&buf[3],Device_Value.WEIGHING_1_Report);
			len = 3+8;	
			break;
		case  IOT__UNIT_INDEX__WEIGHING_2:
			buf[1] = 0;
			buf[2] = 8;
			int64ToUint8(&buf[3],Device_Value.WEIGHING_2_Report);
			len = 3+8;	
			break;
	
		case  IOT__UNIT_INDEX__TRASH_CAPACITY_1:
			buf[1] = 0;
			buf[2] = 8;
			int64ToUint8(&buf[3],Device_Value.TRASH_CAPACITY_1_Report);
			len = 3+8;
			break;
			
		case  IOT__UNIT_INDEX__TRASH_CAPACITY_2:
			buf[1] = 0;
			buf[2] = 8;
			int64ToUint8(&buf[3],Device_Value.TRASH_CAPACITY_2_Report);
			len = 3+8;
			break;
					


		case  IOT__UNIT_INDEX__PLATE_1:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.PLATE_1_Report;
			len = 4;
			break;		
		
		case  IOT__UNIT_INDEX__PLATE_2:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.PLATE_2_Report;
			len = 4;

			break;		
		
		case  IOT__UNIT_INDEX__IC_CARD:
			buf[1] = 0;
			buf[2] = 4;
			int32ToUint8(&buf[3],Device_Value.IC_CARD);
			len = 3+4;
			break;	

		case  IOT__UNIT_INDEX__IC_BLOCK_2:
			buf[1] = 0;
			buf[2] = sizeof(Device_Value.VERSION);
			memcpy(&buf[3], (UINT8*)Device_Value.IC_BLOCK_2, 16);
			len = 3 + 16;		
			break;			
		case  IOT__UNIT_INDEX__LIGHT_INSIDE_1:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.LIGHT_INSIDE_1_Report;
			len = 4;

			break;	
		case  IOT__UNIT_INDEX__LIGHT_INSIDE_2:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.LIGHT_INSIDE_2_Report;
			len = 4;
			break;	

		case  IOT__UNIT_INDEX__LIGHT_OUTSIDE_1:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.LIGHT_OUTSIDE_1_Report;
			len = 4;
			break;	
		case  IOT__UNIT_INDEX__LIGHT_OUTSIDE_2:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.LIGHT_OUTSIDE_2_Report;
			len = 4;
			break;	
		
		case IOT__UNIT_INDEX__TEMPERATURE:
			buf[1] = 0;
			buf[2] = 8;
			int64ToUint8(&buf[3],Device_Value.TEMPERATURE_Report);
			len = 3+8;
			break;	
		
		case IOT__UNIT_INDEX__LOCK_1:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.LOCK_1_Report;
			len = 4;
			break;
		case IOT__UNIT_INDEX__LOCK_2:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.LOCK_2_Report;
			len = 4;	
			break;
		case IOT__UNIT_INDEX__SENSOR_1:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.SENSOR_1_Report;
			len = 4;
			break;
		case IOT__UNIT_INDEX__SENSOR_2:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.SENSOR_2_Report;
			len = 4;	
			break;
		case IOT__UNIT_INDEX__FAN:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = Device_Value.FAN_Setting;
			len = 4;		
			break;
		case IOT__UNIT_INDEX__RUNNING_ERROR:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = IOT__ERROR_CODES__ERROR;
			len = 4;		
			break;
		case IOT__UNIT_INDEX__RUNNING_STATUS:
			buf[1] = 0;
			buf[2] = 1;
			buf[3] = IOT__STATUS_CODES__NONE;
			len = 4;		
			break;
		default:
			break;
		
	}	
	XRJ_mutex_unlock(&Device_Value.Lock);
	return len;
}

/********************需修改部分*******eeeee****************************************************/



//-------------------------------发送应答命令------------------------------------------------------------------------------------------------------
//-------------------------------发送应答命令------------------------------------------------------------------------------------------------------

INT32 Send_Response_Message(Iot__ResultCodes ResultCodes, Iot__ErrorCodes ErrorCodes, UINT16 session,INT32 index)
{
	UINT32 len;
	INT32 ret;
	UINT8 buf[512];
	int16ToUint8(&buf[0], session);
	buf[2] = IOT__ACTION_CODES__RESPONSE;
	buf[3] = 1;
	if (ResultCodes != IOT__RESULT_CODES__RST_SUCCESS)
	{	
		ret = Value_To_TLV(&buf[4], IOT__UNIT_INDEX__RUNNING_ERROR);
	}
	else{
		ret = Value_To_TLV(&buf[4], index);
	}
	
	
	if (ret < 0){
		return -1;
	}
	//==0xff不校验
	buf[ret+4] = checkSum(&buf[0], ret + 4);
	len = ret+5; 	
	//===以64为单位分配空间
	UINT8* txBuf  = malloc((len*2+64)/64*64);
	
	byteTo4BitArray(buf, txBuf, len);
	

	if (TxPacket_Init(txBuf,len*2+2, session,1,Flag_Response) == 0)
	{
		printf("Send_Response_Message: session=[%d]\n", session);	
//		INT32 i;
//		for (i = 0; i < len ; i++)
//		{
//			if ((i%16) == 0)
//			{
//				printf("\n");
//			}	
//			printf("%02x ", ((UINT8*)buf)[i]);
//		}	
//		printf("\n");
	}		
	else
	{	//----to do ----------
		printf("Send_Response_Message FULL \n");	
	}	
	
	
	return 0;
}
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------



//-------------------------------发送上报命令------------------------------------------------------------------------------------------------------
//-------------------------------发送上报命令------------------------------------------------------------------------------------------------------


INT32 Send_Report_Message(INT32 index, St_Session_Flag *Session_Flag)
{
	UINT32 len;
	INT32 ret;
	UINT16 session = Session_GetNew();
	UINT8 buf[512];

	int16ToUint8(&buf[0], session);
	buf[2] = IOT__ACTION_CODES__REPORT;
	buf[3] = 1;
	ret = Value_To_TLV(&buf[4], index);
	if (ret < 0){
		return -1;
	}
	//==0xff不校验
	buf[ret+4] = checkSum(&buf[0], ret + 4);

	len = ret+5; 	
	//===以64为单位分配空间
	UINT8* txBuf  = malloc((len*2+64)/64*64);
	
	byteTo4BitArray(buf, txBuf, len);
		
	if (TxPacket_Init(txBuf, len*2+2, session,1,Flag_Response) == 0)
	{
		printf("Send_Report_Message send: session=[%d]\n",session);	
		if (Session_Flag != NULL)
		{	
			Session_Flag->session = 1;
		}
	}		
	else
	{	//----to do ----------
		printf("Send_Report_Message FULL \n");
		return -2;
	}	
	return 0;
}


//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------


//-------------------------------QUERY-处理-----------------------------------------------------------------------------------------------------
//-------------------------------QUERY-处理-----------------------------------------------------------------------------------------------------
INT32 CONDUCT_Query(UINT8 *buf , Iot__ResultCodes *ResultCodes, Iot__ErrorCodes *ErrorCodes)
{
	INT32 i;
	INT32 id = -1;
	*ResultCodes = IOT__RESULT_CODES__RST_ERROR;
	*ErrorCodes = IOT__ERROR_CODES__HARDWARE_MISMATCH;
	for (i = 0; i < Device_NUM; i++)
	{
		if (buf[0] == Device[i].index)
		{
			if (Device[i].actionarray & IOT__ACTION_CODES__QUERY)
			{	
				id = Device[i].index;
				*ResultCodes = IOT__RESULT_CODES__RST_SUCCESS; 		
			}
			else
			{	//----没有权限			
				*ErrorCodes =  IOT__ERROR_CODES__NOT_SUPPORTED;
				*ResultCodes = IOT__RESULT_CODES__RST_ERROR; 
			}	
			break;
		}
		
	}	
	return id;
}
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------

//------------------------------Setting--处理-------------------------------------------------------------------------------------------------------
//------------------------------Setting--处理-------------------------------------------------------------------------------------------------------

INT32 CONDUCT_Setting(UINT8 *buf , Iot__ResultCodes *ResultCodes, Iot__ErrorCodes *ErrorCodes)
{
	INT32 i;

	*ResultCodes = IOT__RESULT_CODES__RST_ERROR;
	*ErrorCodes = IOT__ERROR_CODES__HARDWARE_MISMATCH;
	
	for (i = 0; i < Device_NUM; i++)
	{
		if (buf[0] == Device[i].index)
		{
			if (Device[i].actionarray & IOT__ACTION_CODES__SETTING)
			{	
				TLV_To_Value(buf);
				*ResultCodes = IOT__RESULT_CODES__RST_SUCCESS; 		
			}
			else
			{	//----没有权限			
				*ErrorCodes =  IOT__ERROR_CODES__NOT_SUPPORTED;
				*ResultCodes = IOT__RESULT_CODES__RST_ERROR; 
			}	
			break;
		}
	}
	return 0;
}	
//------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------





INT32 CONDUCT_OTA(UINT8 *buf , Iot__ResultCodes *ResultCodes, Iot__ErrorCodes *ErrorCodes)
{
	UINT8 type = buf[0];
	
	if ((type == IOT__UNIT_INDEX__OTA_START) 
		&& (OTA_FLASH.Start != FLAG_OTA_RESET))
	{
		 OTA_START(buf, ResultCodes, ErrorCodes);
	}		
	else if ((type == IOT__UNIT_INDEX__OTA_BYTES)
		&& (OTA_FLASH.Start == FLAG_OTA_DOING))	
	{	
		OTA_PACKET(buf, ResultCodes, ErrorCodes);
	}
	else
	{
		*ResultCodes = IOT__RESULT_CODES__RST_ERROR;
		*ErrorCodes = IOT__ERROR_CODES__NOT_SUPPORTED;
	}	
	return 0;
}











INT32 Wrapper_Decode_Product(UINT8 * buf, INT32 len)
{	
	Iot__ResultCodes ResultCodes; 
	Iot__ErrorCodes ErrorCodes;
	INT32 id;
	
	UINT8 cmd =  buf[2];
	//UINT8 packet = buf[3];  //目前仅支持1	
	UINT8 *pTLV = &buf[4];
	UINT16 session = buf[0];
	session = (session<<8) + buf[1];
	
	if (cmd == IOT__ACTION_CODES__RESPONSE)
	{	//-------To  Do  应答为失败内容时，可根据具体实例操作   
		Session_Release(session);
	}
	else if (cmd == IOT__ACTION_CODES__REPORT)
	{
		printf("XRJIOT__ACTION_CODES__REPORT :");
		Send_Response_Message(IOT__RESULT_CODES__RST_ERROR, IOT__ERROR_CODES__NOT_SUPPORTED, session, -1);
	}	
	else if (cmd== IOT__ACTION_CODES__QUERY)
	{
		printf(" IOT__ACTION_CODES__QUERY :\n");
		id = CONDUCT_Query(pTLV, &ResultCodes, &ErrorCodes);
		Send_Response_Message(ResultCodes, ErrorCodes, session,id);
	}	
	else if (cmd== IOT__ACTION_CODES__SETTING)
	{
		CONDUCT_Setting(pTLV, &ResultCodes, &ErrorCodes);
		Send_Response_Message(ResultCodes, ErrorCodes, session, IOT__UNIT_INDEX__RUNNING_STATUS);	
	}	
	else if (cmd == IOT__ACTION_CODES__OTA)
	{
		CONDUCT_OTA(pTLV, &ResultCodes, &ErrorCodes);
		Send_Response_Message(ResultCodes, ErrorCodes, session, IOT__UNIT_INDEX__RUNNING_STATUS);
	}		
	else
	{
		ResultCodes = IOT__RESULT_CODES__RST_ERROR;
		ErrorCodes = IOT__ERROR_CODES__NOT_SUPPORTED;
		Send_Response_Message(ResultCodes, ErrorCodes, session, IOT__UNIT_INDEX__RUNNING_STATUS);
	}	
	printf("=======================================================\n");
	return 0;
}	








void Proto_Product(void)
{
	OSTimeDlyHMSM (0,0,0,16);
	TxPacket_Send_Loop();
	RxPacket_Receive_Loop();
	TxPacket_Realse_Loop();	
}	

UINT32 Proto_CNT = 0;
void Protobuf_Send_test(void)
{
INT32 ret;	
	if (Session_Flag1.enable == 1)
	{
		ret = Session_Poll(Session_Flag1.session); 
		if (ret == 0)
		{//----发送成功
			printf("Protobuf_Send_test  Success!\n");
			Session_Flag1.enable = 0;
		}
		else if (ret == -2)
		{//----未收到应答，发送失败，release	
			Session_FALSE_Release(Session_Flag1.session);
		}		
	}
	else
	{
		Proto_CNT++;
		if (Proto_CNT > 100)
		{
			Proto_CNT = 0;
			printf("\n");
			printf("\n");
			Send_Report_Message(IOT__UNIT_INDEX__LED_1,&Session_Flag1);
			
		}
	}	
}	










INT32	Bit_Set(UINT8 *buf, UINT32 size, UINT32 BitOffset)
{
	UINT32 offset;	
	UINT32 Nbit;
	offset = BitOffset/8;
	Nbit = BitOffset%8;
	if (offset < size)
	{
		buf[offset] |= (1<<Nbit);
		return 0;
	}
	else
	{
		return -1;
	}	
}


INT32	Bit_Check(UINT8 *buf,UINT32 size, UINT32 BitOffset)
{
	
	UINT32 offset;	
	UINT32 Nbit;
	INT32  ret;
	
	offset = BitOffset/8;
	Nbit = BitOffset%8;
	if (offset < size)
	{
		if (buf[offset]&(1<<Nbit))
		{
			ret = 1; 
		}	
		else
		{
			ret = 0;
		}	
	}
	else
	{
		ret = -1;
	}	
	return ret;
}





void OTA_INIT(void)
{
	OTA_FLASH.Start = FLAG_OTA_IDLE;
}

static UINT8 CRC_CHECK(UINT8 * from,UINT16 size)
{
UINT8  ret = 0x00 ;
UINT16  i;	
		for(i = 0; i < size; i++)
		{
				ret ^= from[i];
		}	
		return ret;
}



INT32 OTA_START(UINT8 *buf, Iot__ResultCodes *ResultCodes, Iot__ErrorCodes *ErrorCodes)
{
	UINT16 len = uint8ToUint16(&buf[1]);	//1 2
	
	OTA_FLASH.hashcode = uint8ToUint32(&buf[3]); 	// 3 4 5 6 	
	OTA_FLASH.vesion = uint8ToUint32(&buf[7]); 		// 7 8 9 10
	OTA_FLASH.packettotal = uint8ToUint32(&buf[11]); // 11 12 13 14
	OTA_FLASH.Start = FLAG_OTA_DOING;
	OTA_FLASH.OnePacketsize = 256;
	
	memset(OTA_FLASH.WriteFlag,0,sizeof(OTA_FLASH.WriteFlag));
	MTD_SPI_Erase_Block_Lock(MTD_Block_Start_PrgUpdate);
	*ResultCodes = IOT__RESULT_CODES__RST_SUCCESS; 			
	return 0;	
}

UINT8 TEST_CHECK = 0;
INT32 OTA_PACKET(UINT8 *buf, Iot__ResultCodes *ResultCodes, Iot__ErrorCodes *ErrorCodes)
{

	INT32 ret = -1;
	UINT32 SpiAddr = 0;
	UINT8 dataend[2] = {0x55,0xaa};
	
	//UINT8 type = buf[0];
	//UINT16 len = uint8ToUint16(&buf[1]);	//1 2
	
	*ResultCodes = IOT__RESULT_CODES__RST_ERROR;
	*ErrorCodes = IOT__ERROR_CODES__HARDWARE_MISMATCH;
	
	
	UINT32 hashcode = uint8ToUint32(&buf[3]); 	// 3 4 5 6 	
	UINT32 version = uint8ToUint32(&buf[7]); 		// 7 8 9 10
	UINT32 packettotal = uint8ToUint32(&buf[11]); // 11 12 13 14
	UINT32 RomIndex = uint8ToUint32(&buf[15]); // 15 16 17 18
	UINT32 check = uint8ToUint32(&buf[19]); // 19 20 21 22
	UINT8 *pContent = &buf[23]; //	23
	
	SpiAddr = RomIndex*256;	

	if ((CRC_CHECK(pContent, 256) == check)
		&& (hashcode == OTA_FLASH.hashcode)
		&& (version == OTA_FLASH.vesion))
	{
		printf("OTA: INDEX[%d]\n",RomIndex);
		TEST_CHECK ^= check;
		if (Bit_Check(OTA_FLASH.WriteFlag,128,RomIndex) == 0)
		{	
			if (MTD_SPI_Set_Write_Lock(MTD_Block_Start_PrgUpdate,  SpiAddr , pContent, 256) == 0)
			{		
				Bit_Set(OTA_FLASH.WriteFlag,128,RomIndex);	
				*ResultCodes = IOT__RESULT_CODES__RST_SUCCESS; 	
				if (OTA_CHECK_END(buf) == 0)
				{
					//---更新完成--------------
					printf("Packet  all success!\n");	
					SpiAddr = (MTD_Block_Num_PrgUpdate*4096-2);
					MTD_SPI_Set_Write_Lock(MTD_Block_Start_PrgUpdate, SpiAddr, dataend, 2);	
					OTA_FLASH.Start = FLAG_OTA_RESET;		
					OTA_FLASH.Cnt_Reset = 0;
				}		
				ret = 0;
			}	
			else
			{	
				*ErrorCodes =  IOT__ERROR_CODES__NOT_SUPPORTED;
				*ResultCodes = IOT__RESULT_CODES__RST_ERROR; 			
				ret = -1;
			}	
		}
		else
		{
				*ResultCodes = IOT__RESULT_CODES__RST_SUCCESS;			
				ret = 0;
		}	
	}		
		
	return ret;
}





INT32 OTA_CHECK_END(UINT8 *OtaMessage)
{
	UINT32 AllRomIndex;
	UINT32 i = 0;
	INT32 ret = 0;
	UINT32 SpiAddr = 0;
	UINT8  RomCheckProc = 0;
	
	AllRomIndex = OTA_FLASH.packettotal;
	for (i=0; i < AllRomIndex; i++)
	{
		if (Bit_Check(OTA_FLASH.WriteFlag, 128, i) == 0)
		{
			ret = -1;
			break;
		}	
	}	
	if (ret == 0)
	{//全部CHECKSUM
		for( i =0; i < (AllRomIndex); i++)
		{
			RomCheckProc ^= MTD_SPI_GET_Check_Lock(MTD_Block_Start_PrgUpdate,SpiAddr,256);
			SpiAddr += 256;
		}
	//	RomCheckProc ^= MTD_SPI_GET_Check_Lock(MTD_Block_Start_PrgUpdate,SpiAddr, OtaMessage->binaryarray.len);
		
		if (RomCheckProc == OTA_FLASH.hashcode)
		{
			ret = 0;	
		}	
		else
		{
			ret = -2;
		}	
	}	
	return ret;	
}	



void SYSTEM_Reset_Loop(void)
{	
	if (OTA_FLASH.Start == FLAG_OTA_RESET)
	{
		OTA_FLASH.Cnt_Reset++;
		if (OTA_FLASH.Cnt_Reset > 200)
		{
			MCU_Reset();
		}	
	}
}



void Protobuf_task(void *pdata)
{
	LKT4106_PIN_Reset();
	OSTimeDlyHMSM(0,0,0,500);
//	while(PassWord_LKT.FLAG == 0)
//	{	
//		if (Get_Net_Key(PassWord_LKT.BUF) == 0)
//		{
//			PassWord_LKT.FLAG = 1;
//		}	
//		OSTimeDlyHMSM (0,0,0,20);
//	}
	while(1)
	{	
				
		OSTimeDlyHMSM (0,0,0,20);	
		Proto_Product();	
		SYSTEM_Reset_Loop();		
//		Protobuf_Send_test();
	}
}



